package com.xinou.daily_report.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xinou.common.base.config.ApiResponse;
import com.xinou.common.base.exception.BusException;
import com.xinou.common.enumerate.HttpStatusEnum;
import com.xinou.common.util.BeanUtil;
import com.xinou.daily_report.PO.IntegralPO;
import com.xinou.daily_report.PO.daily.DailyScoreAddPO;
import com.xinou.daily_report.VO.integral.IntegralVO;
import com.xinou.daily_report.VO.integral.IntegralCountVO;
import com.xinou.daily_report.VO.integral.IntegralListVO;
import com.xinou.daily_report.entity.SysDaily;
import com.xinou.daily_report.entity.SysIntegral;
import com.xinou.daily_report.enumerate.SysConfigEnum;
import com.xinou.daily_report.mapper.SysIntegralMapper;
import com.xinou.daily_report.service.SysDailyService;
import com.xinou.daily_report.service.SysIntegralService;
import com.xinou.daily_report.utils.ConstUtil;
import com.xinou.daily_report.utils.DailyShiroUtil;
import com.xinou.sso.service.SysDeptService;
import com.xinou.sso.service.SysUserService;
import com.xinou.sso.util.ShiroUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @创建人 wdl
 * @创建时间 2021/4/28
 * @描述
 */
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class SysIntegralServiceImpl extends ServiceImpl<SysIntegralMapper, SysIntegral> implements SysIntegralService {

    private final SysUserService sysUserService;
    private final SysDeptService sysDeptService;
    private final SysDailyService sysDailyService;
    private final SysIntegralMapper sysIntegralMapper;


    @Override
    public ApiResponse<IntegralListVO> integralList(IntegralPO po) {
        Page<SysIntegral> page = new Page<>(po.getPageNumber(), po.getPageSize());
        return new ApiResponse<>(this.baseMapper.integralList(page, po));
    }

    @Override
    public ApiResponse<IntegralCountVO> integralCount(IntegralPO po) {
        IntegralCountVO vo = new IntegralCountVO();
        Map<Integer, BigDecimal> info = this.baseMapper.integralCount(po)
                .stream()
                .collect(Collectors.toMap(IntegralCountVO::getType, IntegralCountVO::getSum,(k1, k2) -> k1));
        vo.setInfo(info);
        return new ApiResponse<>(vo);
    }

    @Override
    public ApiResponse<Void> integralSave(IntegralPO po) {
        if (po.getReason().length() > 200) {
            throw new BusException(HttpStatusEnum.RE_CODE_DATABASE_ERROR, "添加积分失败,原因长度过长");
        }
        if (po.getIntegralType()==0){
            po.setTheIntegral(-po.getTheIntegral());
        }
        if (po.getAddUserId() == null){
            po.setAddUserId(ShiroUtil.getUserId());
        }
//        po.setDeptId(sysUserService.getById(po.getUserId()).getDeptId());
        SysIntegral sysIntegral = BeanUtil.beanA2beanB(po, SysIntegral.class);
        sysIntegral.setSaveDate(LocalDate.now());
        boolean flag = save(sysIntegral);
        if (!flag) {
            throw new BusException(HttpStatusEnum.RE_CODE_DATABASE_ERROR, "添加积分失败");
        }
        return new ApiResponse<>();
    }


    @Override
    public ApiResponse<IntegralVO> integralGetById(IntegralPO integralPO) {
        return new ApiResponse<IntegralVO>(BeanUtil.beanA2beanB(getById(integralPO.getId()), IntegralVO.class));
    }

    @Override
    public ApiResponse<IntegralVO> integralPersonalRank(IntegralPO integralPO) {
        Page<IntegralPO> page = new Page<>(integralPO.getPageNumber(), integralPO.getPageSize());
        Page<IntegralVO> integralVOPage = sysIntegralMapper.integralPersonMapperList(page, integralPO);
        int index=1;
        for (IntegralVO record : integralVOPage.getRecords()) {
            record.setRank(index++);
        }
        return new ApiResponse<>(integralVOPage.getRecords(),integralVOPage.getTotal());
    }


    @Override
    public ApiResponse<IntegralVO> integralTeamRank(IntegralPO integralPO) {
        Page<IntegralPO> page = new Page<>(integralPO.getPageNumber(), integralPO.getPageSize());
        Page<IntegralVO> integralVOPage = sysIntegralMapper.integralTeamMapperList(page, integralPO);
        int index=1;
        for (IntegralVO record : integralVOPage.getRecords()) {
            record.setRank(index++);
        }
        return new ApiResponse<>(integralVOPage.getRecords(),integralVOPage.getTotal());
    }

    @Override
    public ApiResponse<Void> integralDailyScoreAdd(DailyScoreAddPO po) {
        if (po.getDailyId() == null) {
            throw new BusException("加分失败！");
        }
        if (!DailyShiroUtil.isLead()) {
            throw new BusException("只有领导和小组长才能加分！");
        }
        if(po.getAddScore()>3||po.getAddScore()<0){
            throw new BusException("单次加分请在0到3范围间");
        }
        SysDaily dailyServiceById = sysDailyService.getById(po.getDailyId());
        if (dailyServiceById == null) {
            throw new BusException("日报不见了");
        }
        if (dailyServiceById.getIsAddedScore().equals(Boolean.TRUE)) {
            throw new BusException("该日报已经被加过分了，不能重复加分！");
        }
        if (count(new LambdaQueryWrapper<SysIntegral>()
                .eq(SysIntegral::getIntegralType, ConstUtil.INTEGRAL_TYPE_DAILY_ADD_SCORE)
                .eq(SysIntegral::getSaveDate, LocalDate.now())
                .eq(SysIntegral::getAddUserId, ShiroUtil.getUserId()
                )) >= SysConfigEnum.DEFAULT_MAX_SCORE_ADD_TIMES.getValue()) {
            throw new BusException("您每日最多只能给" + SysConfigEnum.DEFAULT_MAX_SCORE_ADD_TIMES.getValue() + "个日报加分");
        }
        sysDailyService.updateById(dailyServiceById.setIsAddedScore(true));
        save(new SysIntegral()
                .setReason("领导日报加分")
                .setSaveDate(LocalDate.now())
                .setIntegralType(ConstUtil.INTEGRAL_TYPE_DAILY_ADD_SCORE)
                .setTheIntegral(po.getAddScore().doubleValue())
                .setUserId(dailyServiceById.getWorkerId())
                .setAddUserId(ShiroUtil.getUserId()));
        return new ApiResponse<>();
    }

}
